package config

import (
	"anders-cli/pkg/logger"
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
)

type Config struct {
	System struct {
		DebugLogEnabled bool   `json:"debug_log_enabled"`
		Description     string `json:"description,omitempty"`
	} `json:"system"`

	Ollama struct {
		DisableProxy     bool   `json:"disable_proxy"`
		Description      string `json:"description,omitempty"`
		Model            string `json:"model"`
		DescriptionModel string `json:"description_model,omitempty"`
		Host             string `json:"host"`
		DescriptionHost  string `json:"description_host,omitempty"`
	} `json:"ollama"`

	LMStudio struct {
		BaseURL            string `json:"base_url"`
		DescriptionBaseURL string `json:"description_base_url,omitempty"`
		Model              string `json:"model"`
		DescriptionModel   string `json:"description_model,omitempty"`
		ApiKeyEnv          string `json:"api_key_env"`
		DescriptionApiKey  string `json:"description_api_key,omitempty"`
	} `json:"lmstudio"`

	XAI struct {
		BaseURL            string `json:"base_url"`
		DescriptionBaseURL string `json:"description_base_url,omitempty"`
		Model              string `json:"model"`
		DescriptionModel   string `json:"description_model,omitempty"`
		ApiKeyEnv          string `json:"api_key_env"`
		DescriptionApiKey  string `json:"description_api_key,omitempty"`
	} `json:"xai"`

	General struct {
		DefaultBackend     string `json:"default_backend"`
		DescriptionBackend string `json:"description_backend,omitempty"`
		MaxContextLength   int    `json:"max_context_length"`
		DescriptionContext string `json:"description_context,omitempty"`
	} `json:"general"`

	MultiAgent struct {
		DefaultMode             string            `json:"default_mode"` // "expert" or "team"
		DescriptionMode         string            `json:"description_mode,omitempty"`
		MaxFeedbackRounds       int               `json:"max_feedback_rounds"` // 最大反馈轮次，默认3
		DescriptionRounds       string            `json:"description_rounds,omitempty"`
		EnabledAgents           []string          `json:"enabled_agents"` // 启用的子Agent列表
		DescriptionAgents       string            `json:"description_agents,omitempty"`
		AILangThreshold         int               `json:"ailang_threshold"` // AILang使用阈值，默认90
		DescriptionThreshold    string            `json:"description_threshold,omitempty"`
		ConflictThreshold       int               `json:"conflict_threshold"` // 冲突决断阈值，默认90
		DescriptionConflict     string            `json:"description_conflict,omitempty"`
		QueryTimeout            int               `json:"query_timeout"` // 查询超时时间（秒），默认30
		DescriptionTimeout      string            `json:"description_timeout,omitempty"`
		AgentTimeout            int               `json:"agent_timeout"` // 单个Agent超时时间（秒），默认15
		DescriptionAgentTimeout string            `json:"description_agent_timeout,omitempty"`
		Roles                   map[string]string `json:"roles"` // 角色映射配置
		DescriptionRoles        string            `json:"description_roles,omitempty"`
		RulesPath               string            `json:"rules_path"` // Rules文件路径，默认"./rules"
		DescriptionRulesPath    string            `json:"description_rules_path,omitempty"`
	} `json:"multi_agent"`
}

var globalConfig *Config

// Load 加载配置文件
func Load(configPath string) error {
	// 使用defer/recover来捕获可能的panic
	defer func() {
		if r := recover(); r != nil {
			logger.Error("配置加载发生panic: %v", r)
		}
	}()

	// 尝试多个可能的配置文件位置
	possiblePaths := []string{
		configPath,
		filepath.Join(".", configPath),
		filepath.Join("configs", configPath),
		filepath.Join(os.Getenv("HOME"), ".anders-cli", configPath),
	}

	var configFile *os.File
	var err error

	for _, path := range possiblePaths {
		if path == "" {
			continue
		}
		configFile, err = os.Open(path)
		if err == nil {
			logger.Info("找到配置文件: %s", path)
			break
		}
	}

	if err != nil {
		logger.Warn("无法找到配置文件，已尝试的路径: %v", possiblePaths)
		// 不返回错误，而是初始化默认配置
		globalConfig = &Config{}
		setDefaults()
		logger.Info("使用默认配置")
		return nil
	}
	defer func() {
		if configFile != nil {
			configFile.Close()
		}
	}()

	// 检查文件大小，避免加载过大的文件
	stat, err := configFile.Stat()
	if err != nil {
		logger.Warn("获取文件信息失败: %v", err)
	} else if stat.Size() > 10*1024*1024 { // 10MB限制
		logger.Warn("配置文件过大: %d bytes，使用默认配置", stat.Size())
		globalConfig = &Config{}
		setDefaults()
		return nil
	}

	decoder := json.NewDecoder(configFile)
	globalConfig = &Config{}

	if err := decoder.Decode(globalConfig); err != nil {
		logger.Warn("解析配置文件失败: %v，使用默认配置", err)
		// 解析失败时也使用默认配置
		globalConfig = &Config{}
		setDefaults()
		return nil
	}

	// 验证配置完整性
	if err := validateConfig(globalConfig); err != nil {
		logger.Warn("配置验证失败: %v，使用默认配置", err)
		globalConfig = &Config{}
		setDefaults()
		return nil
	}

	logger.Info("配置文件加载成功")
	return nil
}

// Get 获取全局配置实例
func Get() *Config {
	if globalConfig == nil {
		// 尝试加载默认配置文件
		if err := Load("config.json"); err != nil {
			logger.Warn("无法加载默认配置文件: %v", err)
			// 返回默认配置
			globalConfig = &Config{}
			setDefaults()
		}
	}
	return globalConfig
}

// setDefaults 设置默认配置
func setDefaults() {
	globalConfig.System.DebugLogEnabled = true
	globalConfig.General.DefaultBackend = "lmstudio"
	globalConfig.General.MaxContextLength = 8192
	globalConfig.Ollama.Model = "gemma3:4b"
	globalConfig.Ollama.Host = "http://localhost:11434"
	globalConfig.LMStudio.BaseURL = "http://localhost:1234"
	globalConfig.LMStudio.Model = "openai/gpt-oss-20b"
	globalConfig.XAI.BaseURL = "https://api.x.ai/v1"
	globalConfig.XAI.Model = "grok-4"

	// 多Agent默认配置
	globalConfig.MultiAgent.DefaultMode = "expert"
	globalConfig.MultiAgent.MaxFeedbackRounds = 3
	globalConfig.MultiAgent.EnabledAgents = []string{"business_analyst", "architect"}
	globalConfig.MultiAgent.AILangThreshold = 90
	globalConfig.MultiAgent.ConflictThreshold = 90
	globalConfig.MultiAgent.QueryTimeout = 30
	globalConfig.MultiAgent.AgentTimeout = 15

	// 默认角色配置
	globalConfig.MultiAgent.Roles = map[string]string{
		"pm":        "anders",
		"analyst":   "jim",
		"architect": "neo",
	}
	globalConfig.MultiAgent.RulesPath = "./rules"
}

// validateConfig 验证配置完整性
func validateConfig(cfg *Config) error {
	if cfg == nil {
		return fmt.Errorf("配置为空")
	}

	// 验证必需的字段
	if cfg.General.DefaultBackend == "" {
		return fmt.Errorf("缺少默认后端配置")
	}

	// 验证后端配置
	validBackends := []string{"ollama", "lmstudio", "xai"}
	isValidBackend := false
	for _, backend := range validBackends {
		if cfg.General.DefaultBackend == backend {
			isValidBackend = true
			break
		}
	}
	if !isValidBackend {
		logger.Warn("未知的后端类型: %s，使用默认后端", cfg.General.DefaultBackend)
	}

	// 验证超时设置
	if cfg.MultiAgent.QueryTimeout <= 0 {
		cfg.MultiAgent.QueryTimeout = 120
		logger.Info("QueryTimeout无效，使用默认值: %d秒", cfg.MultiAgent.QueryTimeout)
	}

	if cfg.MultiAgent.AgentTimeout <= 0 {
		cfg.MultiAgent.AgentTimeout = 90
		logger.Info("AgentTimeout无效，使用默认值: %d秒", cfg.MultiAgent.AgentTimeout)
	}

	// 验证MaxFeedbackRounds
	if cfg.MultiAgent.MaxFeedbackRounds <= 0 {
		cfg.MultiAgent.MaxFeedbackRounds = 3
		logger.Info("MaxFeedbackRounds无效，使用默认值: %d", cfg.MultiAgent.MaxFeedbackRounds)
	}

	// 验证阈值
	if cfg.MultiAgent.AILangThreshold < 0 || cfg.MultiAgent.AILangThreshold > 100 {
		cfg.MultiAgent.AILangThreshold = 90
		logger.Info("AILangThreshold超出范围，使用默认值: %d", cfg.MultiAgent.AILangThreshold)
	}

	if cfg.MultiAgent.ConflictThreshold < 0 || cfg.MultiAgent.ConflictThreshold > 100 {
		cfg.MultiAgent.ConflictThreshold = 90
		logger.Info("ConflictThreshold超出范围，使用默认值: %d", cfg.MultiAgent.ConflictThreshold)
	}

	// 验证URL格式
	if cfg.LMStudio.BaseURL != "" {
		if !isValidURL(cfg.LMStudio.BaseURL) {
			logger.Warn("LMStudio BaseURL格式无效: %s", cfg.LMStudio.BaseURL)
		}
	}

	if cfg.Ollama.Host != "" {
		if !isValidURL(cfg.Ollama.Host) {
			logger.Warn("Ollama Host格式无效: %s", cfg.Ollama.Host)
		}
	}

	if cfg.XAI.BaseURL != "" {
		if !isValidURL(cfg.XAI.BaseURL) {
			logger.Warn("XAI BaseURL格式无效: %s", cfg.XAI.BaseURL)
		}
	}

	return nil
}

// isValidURL 简单验证URL格式
func isValidURL(url string) bool {
	if len(url) < 7 {
		return false
	}
	return url[:7] == "http://" || (len(url) >= 8 && url[:8] == "https://")
}
